import BadgeManage from "../badge/BadgeManage";
import EventManage from "../event/EventManage";
import { Logger } from "../log/logger";
import { ClassUI, gidui } from "./UIDefine";
import { BadgeType } from "../../model/BadgeType";
import UIUtils from "../utils/UIUtils";
import UIConfig from "../config/UIConfig";
import PoolObj from "../pool/PoolObj";
import PromiseEx from "../utils/PromiseEx";
import Utils from "../utils/Utils";

export default abstract class BaseUI<T extends Laya.Scene, D = any>{

    static CLOSE: string = "close";
    static CANCEL: string = "cance";

    static GID() {
        let gid = this["$_GIDUI"];
        if (!gid) {
            gid = gidui();
            Object.defineProperty(this, "$_$GIDUI", {
                value: gid,
                configurable: false,
                writable: false,
                enumerable: true
            });
        }

        return gid;
    }

    private _view: T;
    private _data: D;
    private _gid: number;
    private _opened: boolean;
    private _ready: boolean = false;
    private _readyPms: PromiseEx;
    private _maskLayer: maskConContainer;

    protected mask: boolean = false;
    protected clickOther: boolean = false;

    protected constructor(ui: ClassUI<T>, gid: number) {
        this._readyPms = new PromiseEx();
        this._gid = gid;
        this.__createView(ui);
    }

    /**@private */
    onCreated() {
        this._view.size(Laya.stage.width, Laya.stage.height);
        this._onClick();
        this._ready = true;
        this._readyPms.resolve();
        this._runByName("onInit");
    }


    /**页面初始化时调用 */
    // onInit() {

    // }

    /**打开时回调 */
    // onOpen() {

    // }

    /**关闭时候回调 */
    // onClose(close: any) {

    // }

    /**destory时回调 */
    // onDestory() {

    // }

    /**进入动画 */
    // onFadeIn(v: T) {

    // }

    close(v?: any) {
        EventManage.I.closeUI(this._gid, v)
    }

    /**
     * @private
     */
    open() {
        if (this._ready) {
            openView.call(this);
        } else {
            this._readyPms.then(openView.bind(this))
        }

        function openView(this: any) {
            if (this.mask) {
                this._maskLayer = maskConContainer.create();
                this._view.addChildAt(this._maskLayer, 0);

                this.clickOther && this._maskLayer.on(Laya.Event.CLICK, this, this.close, ["click_other"]);
            }

            this._runByName("onOpen");
            this._runByName("onFadeIn", this.view)
            this._opened = true;
        }

    }

    /**@private */
    closeSelf(v?: any) {
        if (!this._opened) return;
        this._opened = false;
        // this.onClose(v);
        // BadgeManage.I.unRegistAll(this);
        this._runByName("onClose", v)
        this._data = null;
        if (this._maskLayer) {
            this._maskLayer.offAll();
            maskConContainer.recover(this._maskLayer);
            this._maskLayer = null;
        }
    }

    /**窗口大小改变 */
    onResize() {

    }

    /**@private */
    destory(reason?: any) {
        this._runByName("onDestory", reason);
        this.__destory();
        this._view.destroy();
        this._view = null;

    }

    protected onClick(target: Laya.Sprite, fun: Function, ages?: any[]) {
        UIUtils.addClick(target, fun, this, ages);
    }

    protected onClickOne(target: Laya.Sprite, fun: Function, ages?: any[]) {
        UIUtils.addClick(target, fun, this, ages, true);
    }

    protected unClick(target: Laya.Sprite) {
        target.offAll(Laya.Event.CLICK)
    }

    protected on(type: string, listener: Function, args?: any[]) {
        EventManage.I.on(type, this, listener, args)
    }

    /**
     * 注册红点
     * @param target 
     * @param type 
     */
    protected prepare<T extends Laya.Sprite>(target: T, type: BadgeType) {
        BadgeManage.I.regist(type, target, this, true);
    }

    protected unPrepare(sp: Laya.Sprite, type?: BadgeType) {
        BadgeManage.I.unRegist(sp, type, this)
    }


    protected get view() {
        return this._view;
    }

    protected get age() {
        return this._data;
    }

    get opened() {
        return this._opened;
    }

    private __destory() {
        BadgeManage.I.unRegistAll(this);
        if (this.opened) {
            this.close()
        }
    }


    private __createView(ui: ClassUI<T>) {
        if (!Utils.isNil(this._view)) {
            Logger.logBusiness(`重复实例${ui.name}`);
        } else {
            this._view = new ui();
        }
        this._view.waitOpen.then(() => this.onCreated());
    }

    private _onClick(): void {
        let btns = [BaseUI.CLOSE, BaseUI.CANCEL];
        for (let item of btns) {
            let btn = this._view["btn_" + item];
            if (btn) {
                UIUtils.addClick(btn, this.close, this)
            }
        }
    }

    private _runByName(name: string, ...ages: any[]) {
        let fun = this[name];
        if (!fun || typeof fun !== "function") return;

        fun.apply(this, ages);
    }
}

class maskConContainer extends Laya.Sprite {

    static create(): maskConContainer {
        let v = PoolObj.getItemByClass("maskConContainer", maskConContainer);
        v.name = "viewMask";
        return v;
    }

    static recover(v: maskConContainer) {
        v.removeSelf();
        PoolObj.recover("maskConContainer", v);
    }

    // maskLayer: Laya.Sprite = new Laya.Sprite();

    clickHander: Laya.Handler;

    constructor() {
        super();

        let width = Laya.stage.width;
        let height = Laya.stage.height;

        this.size(width, height);
        this.size(width, height);
        this.graphics.clear(true);
        this.graphics.drawRect(0, 0, width, height, UIConfig.popupBgColor);
        this.alpha = UIConfig.popupBgAlpha;

        // this.loadImage("images/component/tip_bg.png");

    }

}